﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
namespace ObjControler
{
    public unsafe class Object3D : IDisposable
    {
        private string m_Name;
        private ulong m_ID;
        private float* m_position;
        private float m_Size;
        private BoundingBox m_Bbox;
        private List<IElement> m_Elements;

        public BoundingBox Bbox
        {
            get { return m_Bbox; }
            set { m_Bbox = value; }
        }
        public List<IElement> Elements
        {
            get { return m_Elements; }
            set { m_Elements = value; }
        }
        public void AddElement(IElement element)
        {
            m_Elements.Add(element);
        }
        public float Size
        {
            get { return m_Size; }
            set { m_Size = value; }
        }
        public unsafe Vector3 Position
        {
            get
            {
                Vector3 tmp = new Vector3(

                    m_position[0],
                    m_position[1],
                    m_position[2]
                    );

                return tmp;
            }
            set
            {

                m_position[0] = value.X;
                m_position[1] = value.Y;
                m_position[2] = value.Z;

                CalkBBox();
            }
        }
        public ulong ID
        {
            get { return m_ID; }
            set { m_ID = value; }
        }
        public string Name
        {
            get { return m_Name; }
            set { m_Name = value; }
        }

        public Object3D()
        {
            m_Size = 1;
           init();
            m_Name = "DefObj";
            m_ID = 0;
            m_Elements = new List<IElement>(0);
         
        }
        public Object3D(string name,ulong id,Vector3 pos,float size)
        {
             m_Size = size;
            init();
            m_Name = name;
            m_ID = id;
            Position = pos;
           
            m_Elements = new List<IElement>(0);
            
        }
        public float IntersectObject(float x, float y, float z)
        {
            float result = 0;
            ContainmentType Containment = m_Bbox.Contains(new Vector3(x, y, z));
            if (
               Containment == ContainmentType.Contains || Containment == ContainmentType.Intersects
                )
            {
                result = 1;
                for (int i = 0; i < m_Elements.Count; i++)
                {
                    if (m_Elements[i].Bbox.Intersects(m_Bbox))
                    {
                         float sval = m_Elements[i].function(x, y, z);
                         result += sval * sval;
                    }
                   
                }
            }

            return result;
        }
        private unsafe void init()
        {

            
            m_position = (float*)Marshal.AllocHGlobal(sizeof(float) * 3);          
            m_position[0] = 0;
            m_position[1] = 0;
            m_position[2] = 0;

            CalkBBox();
        }
        private unsafe void CalkBBox()
        {
           // if (m_Elements.Count == 0)
           // {
            float BoxS =m_Size / 2;
            Vector3 min = new Vector3(m_position[0] - BoxS, m_position[1] - BoxS, m_position[2] - BoxS);
            Vector3 max = new Vector3(m_position[0] + BoxS, m_position[1] + BoxS, m_position[2] + BoxS);
            m_Bbox = new BoundingBox(min, max);
           // }
            //else
            //{

            //    List<Vector3> points = new List<Vector3>();
            //    for (int i = 0; i < m_Elements.Count; i++)
            //    {
            //        points.Add(m_Elements[i].Bbox.Min);
            //        points.Add(m_Elements[i].Bbox.Max);
            //    }
            //    m_Bbox = BoundingBox.CreateFromPoints(points);
            //}

        }


        public void Dispose()
        {
            
            Marshal.FreeHGlobal((IntPtr)m_position);           
            m_Elements.Clear();
        }
    }
}
